
/**	
*	
	Ford circles : another try in circle/spher packing
*/

import ij.ImagePlus;
import ij.plugin.PlugIn;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;


import java.awt.Color;
import java.awt.Font;
import java.awt.Polygon;
import java.io.PrintStream;


import java.util.Locale;
import java.util.Random; 




import pluginUtils.Circle;
import pluginUtils.Complexe;



public class FordCirclesOnSphere extends ImagePlus implements PlugIn{
	{Locale.setDefault(Locale.US); }
	
	private ImageProcessor primeIP; 
	private int X=2000,Y=2000; // image size
	
	private Random generator=new Random(); // One always needs some randomness
	
	// For the scaling of the image
	private double x0=0,x1=1,y0=0,y1=1;
	private double acoef,ccoef,vcoef,wcoef; 
	
	
	
	public void setCoefs(){
		acoef=X/(x1-x0); 
		vcoef=Y/(y1-y0); 
		ccoef=-acoef*x0; 
		wcoef=-vcoef*y0; 
	}
	 
	private PrintStream output;
	
	public void setBounds(double xl,double xu,double yl,double yu){
		x0=xl; 
		x1=xu;
		y0=yl;
		y1=yu; 
	}
	
	
	private boolean premier(int p,int q){
		while(p!=q){
			if(p>q) p=p-q; 
			else q=q-p; 
		}
		return (q==1);
	}
	
	
	
	private void drawCircle(Circle c,int q){
		//if(intersect(c))return; 
		
		//if(c.getRadius()<0.1) return; 
		int intX=(int)(c.getCenter().getReal()*acoef+ccoef);
		int intY=(int)(c.getCenter().getIm()*vcoef+wcoef);
		int intRx=(int)(c.getRadius()*acoef);
		int intRy=(int)(c.getRadius()*vcoef);
		
		int rank=q%6; 
		
		
		
			
			primeIP.fillOval(intX-intRx,intY-intRy,intRx*2,intRy*2);	
			
			
			String s="sphere{<"+c.getCenter().getReal()+",0,"+c.getCenter().getIm()+">,";
			s+=c.getRadius(); 
			s+=" texture{Texture"+rank+"} finish{Finish"+rank+"}}"; 
			System.out.println(s);
			output.println(s);	
		}
	
	
	
	
	
	private void drawLine(double xd,double yd,double xf,double yf){
		int XD=(int)(xd*acoef+ccoef); 
		int YD=(int)(yd*vcoef+wcoef); 
		int XF=(int)(xf*acoef+ccoef); 
		int YF=(int)(yf*vcoef+wcoef);
		primeIP.drawLine(XD,YD,XF,YF); 
	}
	
	

	
	
	
	
	public void run(String arg){
		
		
		primeIP = new ColorProcessor(X,Y);
		
		setBounds(-1,1,-1,1); 
		setCoefs(); 
		
		
		
		
		
		
		Polygon background=new Polygon(new int[]{0,0,X,Y},new int[]{0,X,Y,0},4);
		primeIP.setColor(Color.WHITE);
		
		primeIP.fillPolygon(background);
		
		
		primeIP.setFont(new Font(null,Font.ITALIC,60));
		primeIP.setColor(Color.BLACK);
		primeIP.setLineWidth(5); 
		
		drawLine(0,y0,0,y1); 
		drawLine(x0,0,x1,0);
		
		//primeIP.moveTo(150,80); 
		//primeIP.drawString("a="+a+"\n"+"b="+b+"\n"+"n="+n+"\n"+"m="+m);
	
		setProcessor("Verifying", primeIP);
		/************************ The drawing begins here *******************************/
		int nbCircles=0; 
		try{
			output=new PrintStream("/tmp/outFord.txt"); 
			for(int q=1; q<100;q++)
			{
				for(int p=1;p<q;p++){
					if(premier(p,q)){
						// Coordonnees du centre
						double x=p/(q+0.0); 
						double y=1.0/(2.0*q*q); 
						double denom=1/(x*x+y*y+1); 
						double xcs=2*x*denom; 
						double ycs=2*y*denom; 
						double zcs=(x*x+y*y-1)*denom; 
						
						// Coordonnees d'un point de la circonference
						double xp=p/(q+0.0); 
						double yp=0; 
						double denom2=1/(x*x+1); 
						double xps=2*xp*denom2; 
						double yps=2*yp*denom2; 
						double zps=(xp*xp-1)*denom2; 
						System.out.println(xps*xps+yps*yps+zps*zps); 
						double radius=Math.sqrt((xcs-xps)*(xcs-xps)+(ycs-yps)*(ycs-yps)+(zps-zcs)*(zps-zcs)); 
						String s="sphere{<"+xcs+","+ycs+","+zcs+">,"+radius+" texture{Texture"+(q%6)+"} finish{Finish"+(q%6)+"}}"; 
							
						
						//System.out.println(s);
						output.println(s);
						
						nbCircles++; 
					}
			}
		}
		
		
		
		
		show();
		System.out.println("**********************************************done "+nbCircles); 
	}
		catch(Exception e){System.out.println("dans le baba"); System.exit(0); }
	}
}
	
	
	